package com.smartum.mpr.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.smartum.mpr.client.services.UserService;
import com.smartum.mpr.server.utils.ConnectionPropertyReader;
import com.smartum.mpr.server.utils.JSONHelper;
import com.smartum.mpr.shared.User;
import org.json.simple.JSONObject;
import org.json.simple.parser.ParseException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

/**
 * Class represents RPC service implementation, related to User domain. Responsible for the deserialization
 * of incoming requests.
 * <p/>
 * Connection url reads from <code>connection.properties</code> file.
 */
public class UserServiceImpl extends RemoteServiceServlet implements UserService {
    public static final String CONNECTION_ISSUE_ERROR_CODE = "CONNECTION_ISSUES";
    public static final String UNDEFINED_USER_ERROR_CODE = "UNDEFINED_USER";

    public User retrieveUser(String username, String userPassword) {
        final User user = new User();

        try {

            final JSONObject webRequestHeader = buildUserRetrievalJSON(username, userPassword);
            final HttpURLConnection conn = JSONHelper.getHttpURLConnection(ConnectionPropertyReader.getUserAuthorizationServiceURL());
            try {
                conn.connect();
            } catch (IOException e) {
                user.setMessage(CONNECTION_ISSUE_ERROR_CODE);
                return user;
            }

            final String response = JSONHelper.proceedRequest(webRequestHeader, conn);
            parseResponse(response, user);

        } catch (IOException e) {
            user.setMessage(UNDEFINED_USER_ERROR_CODE);
        }

        HttpServletRequest request = this.getThreadLocalRequest();
        HttpSession session = request.getSession(true);
        session.setAttribute(JSONHelper.USER_ID, user.getId());
        session.setAttribute(JSONHelper.AUTH_TOKEN, user.getToken());
        session.setAttribute(JSONHelper.USER_NAME, user.getName());

        return user;
    }

    public User retrieveUserFromSesion() {
        final HttpServletRequest request = this.getThreadLocalRequest();
        final HttpSession session = request.getSession(false);

        final User sessionUser = new User();
        sessionUser.setId((Long) session.getAttribute(JSONHelper.USER_ID));
        sessionUser.setName((String) session.getAttribute(JSONHelper.USER_NAME));
        sessionUser.setToken((String) session.getAttribute(JSONHelper.AUTH_TOKEN));

        return sessionUser;
    }

    public void logout() {

        final HttpServletRequest request = this.getThreadLocalRequest();
        final HttpSession session = request.getSession(false);

        if (session == null) {
            return;
        }
        session.invalidate();
    }

    private void parseResponse(String response, User user) {
        try {
            final Map<String, Object> responseJSON = JSONHelper.getResponseJSON(response);

            user.setName((String) responseJSON.get(JSONHelper.USER_NAME));
            user.setId((Long) responseJSON.get(JSONHelper.USER_ID));
            user.setToken((String) responseJSON.get(JSONHelper.AUTH_TOKEN));

        } catch (ParseException e) {
            user.setMessage("UNKNOWN");
        }
    }

    private JSONObject buildUserRetrievalJSON(String username, String userPassword) throws IOException {
        final JSONObject webRequestHeader = JSONHelper.getWebRequestHeader(null);

        JSONObject requestObject = new JSONObject();
        requestObject.put("user_username", username);
        requestObject.put("user_password", userPassword);

        webRequestHeader.put("request", requestObject);
        return webRequestHeader;
    }


}
